home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
UTIL
/
PROGRAMMING
/
RINK010
/
Demo
/
c
/
rinkdemo
next >
Wrap
Text File
|
1995-06-25
|
5KB
|
210 lines
// rinkdemo - main program
// (c) Ben Summers 1995
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "kernel.h"
#include "rink.h"
// this demonstration of rink shows the recommended way of loading
// and using rink segments. However, you don't have to do it like
// this - the run time system just provides some basic routine
// to handle segments, and doesn't force any method of use on you.
typedef int BOOL;
#define TRUE 1
#define FALSE 0
// the function prototypes of the functions in segments.
typedef int (*SegmentStart)(char *, int);
typedef void (*SegmentDo)(void);
typedef int (*SegmentFinish)(int);
typedef void (*SegmentNamed)(void);
// and a structure to hold info about the segments we've loaded
typedef struct {
rink_seghandle Handle;
struct {
SegmentStart Start; // there should be the same number
SegmentDo Do; // of fns here that there are in the header
SegmentFinish Finish; // and they must be in the same order
} fns;
} SegmentInfo;
// a rink_check structure for loading segments
rink_check CheckBlock;
// an error wrapping function
BOOL ErrWrap(void *err, char *Doing)
{
char *String = ((char *)err) + 4;
if(err == 0)
return TRUE;
printf("Error in %s: %s\n", Doing, String);
return FALSE;
}
// some data for segments to access
int NumberInParent = 56;
// a function for the segments to call
int FunctionInParentProgram(int Number)
{
printf("FunctionInParentProgram called, Number = %d\n\n", Number);
return Number / 2;
}
// a routine to load a segment. Takes a pointer to the name
// of the directory the code and links files are stored and
// a Segment info to put the interesting stuff in.
BOOL LoadSegment(SegmentInfo *pSegment, char *Name)
{
char CodeName[256];
char LinksName[256];
_rink_fn *PtrArray;
rink_version *Version;
int Fn;
// make filename of the code and links
sprintf(CodeName, "%s.Code", Name);
sprintf(LinksName, "%s.Links", Name);
// load the segment...
if(!ErrWrap(rink_load(CodeName, LinksName, &pSegment->Handle, &CheckBlock), "segment load"))
return FALSE;
// OK, let's have a look at the version of the segment we've just loaded.
// It might be nice to check them to see that it's acceptable.
// It is a bad plan to alter the returned structure.
Version = rink_readversion(pSegment->Handle);
printf("Segment '%s': Main version = %d, Code version = %d\n\n", Name, Version->main, Version->code);
// right, now get the function pointers...
PtrArray = (_rink_fn *)&pSegment->fns;
for(Fn = 0; Fn < (sizeof(pSegment->fns) / sizeof(_rink_fn)); Fn++)
{
// for each function, get a pointer from the run time system
PtrArray[Fn] = rink_fn(pSegment->Handle, Fn);
// check that it's not zero - ie no function
if(PtrArray[Fn] == 0)
{
printf("Function not present in segment %s\n\n", Name);
return FALSE;
}
}
// done
return TRUE;
}
// routine to unload segments
BOOL UnloadSegment(SegmentInfo *pSegment)
{
// could call a finalise function here...
// unload the segment from memory
rink_unload(pSegment->Handle);
return TRUE;
}
// the main function
int main(void)
{
SegmentInfo Segment1;
SegmentInfo Segment2;
int l;
SegmentNamed Fn;
char *Name;
printf("rink demonstration program\n(c) Ben Summers 1995\n\n");
// set up the check block
strcpy(CheckBlock.id, "rinkdemo");
CheckBlock.main_version = 100;
CheckBlock.code_version = 0;
// load the two segments
printf("Loading segments...\n\n");
if(!LoadSegment(&Segment1, "Segment1"))
return 1;
if(!LoadSegment(&Segment2, "Segment2"))
return 1;
printf("Segments loaded\n\n");
// call a few functions... start with the start functions.
printf("Segment1 Start returned %d\n\n", Segment1.fns.Start("A nice little string", 42));
printf("Segment2 Start returned %d\n\n", Segment2.fns.Start("A pretty string", 19));
// and the do functions
Segment1.fns.Do();
Segment2.fns.Do();
// and finish off with a final
printf("Segment1 Finish returned %d\n\n", Segment1.fns.Finish(12));
printf("Segment2 Finish returned %d\n\n", Segment2.fns.Finish(90));
// call some named functions in Segment1. Now, I'm not really sure what you'd
// do with them, but they're there just in case.
printf("Calling named functions from Segment1...\n\n");
l = 0;
do {
Fn = (SegmentNamed)rink_enum_named(Segment1.Handle, &l, &Name);
printf("*** calling %s\n", Name);
Fn();
} while(l >= 0);
// unload them now we've finished
UnloadSegment(&Segment1);
UnloadSegment(&Segment2);
// all done.
return 0;
}